package cn.roadtrip.mtravelbusinessmodule.bs.comment;

import cn.hutool.http.HttpUtil;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.CoupleComment;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.records.CoupleCommentRecord;
import cn.roadtrip.utilmodule.util.ContentAuditService;
import cn.roadtrip.utilmodule.util.DataBean;
import cn.roadtrip.utilmodule.util.enumpck.Enum_CommentStats;
import cn.roadtrip.utilmodule.util.enumpck.Enum_CommentType;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.github.yitter.idgen.YitIdHelper;
import com.google.gson.Gson;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.*;
import org.jooq.DSLContext;
import org.jooq.impl.DSL;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;

import java.io.File;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static cn.roadtrip.mtravelbusinessmodule.sql.couple.Tables.*;
import static cn.roadtrip.utilmodule.util.DataBean.err;
import static cn.roadtrip.utilmodule.util.DataBean.suc;

/**
 * 评论操作
 */
@Component
public class CommentImpl {

    @Autowired
    private DSLContext dslContext;

    @Autowired
    private ContentAuditService contentAuditService;
    private ExecutorService queryService;

    @Autowired
    private RedissonClient redissonClient;

    @PostConstruct
    public void init() {
        queryService = Executors.newFixedThreadPool(12);
    }

    @PreDestroy
    public void destroy() {
        try {
            queryService.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_createComment {
        private String mainBsId;
        private String content;
        private java.util.List<String> images;
        private String parentId;
        private String userId;
        private Integer starNum;
        private Enum_CommentType commentType;
        private java.util.Map<String, Object> extInfor;
    }

    /**
     * 创建评论
     *
     * @param model
     * @return
     */
    public DataBean createComment(
            Model_createComment model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                String id = "" + YitIdHelper.nextId();
                Gson gson = new Gson();
                dslContext.insertInto(COUPLE_COMMENT)
                        .set(
                                new CoupleCommentRecord(
                                        id,
                                        model.getUserId(),
                                        LocalDateTime.now(),
                                        model.getUserId(),
                                        LocalDateTime.now(),
                                        "",
                                        model.getUserId(),
                                        model.getParentId(),
                                        gson.toJson(model.getImages()),
                                        model.getContent(),
                                        0,
                                        0,
                                        model.getMainBsId(),
                                        "0",
                                        "0",
                                        model.getCommentType().getCode(),
                                        "0",
                                        Enum_CommentStats.WaitAudit.getCode()
                                )
                        ).execute();
                dslContext.commit();

                //审核内容
                queryService.execute(() -> {
                    int needCount = 1;// 需要判定的审核数量
//                    if (!(model.getImages() == null || model.getImages().isEmpty())) {
//                        needCount += model.getImages().size();
//                    }
                    int passnum = 0;
                    //审核文字
                    passnum += contentAuditService.checkContent(model.getContent()) ? 1 : 0;
                    //审核图片
                    if (needCount > 1) {
                        File path = new File("./tmpDownLoad");
                        path.mkdirs();
                        for (String u : model.getImages()) {
                            String fileUrl = "";
                            File destFile = null;
                            if (u.startsWith("http")) {
                                try {
                                    destFile = new File(path, u.substring(u.lastIndexOf("/") + 1));
                                    //下载
                                    HttpUtil.downloadFile(u, destFile);
                                    passnum += contentAuditService.checkContent(destFile.getCanonicalPath()) ? 1 : 0;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {
                                    if (destFile != null) {
                                        destFile.delete();
                                    }
                                }
                            } else if (u.startsWith("/")) {
                                fileUrl = "." + u;
                                destFile = new File(fileUrl);
                                try {
                                    passnum += contentAuditService.checkContent(destFile.getCanonicalPath()) ? 1 : 0;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {
                                    if (destFile != null) {
                                        destFile.delete();
                                    }
                                }
                            } else {
                                fileUrl = "./" + u;
                                destFile = new File(fileUrl);
                                try {
                                    passnum += contentAuditService.checkContent(destFile.getCanonicalPath()) ? 1 : 0;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {
                                    if (destFile != null) {
                                        destFile.delete();
                                    }
                                }
                            }
                        }
                    }

                    if (needCount == passnum) {
                        //审核成功，
                        dslContext.update(
                                COUPLE_COMMENT
                        ).set(
                                COUPLE_COMMENT.STATS, (Enum_CommentStats.Apply.getCode())
                        ).where(
                                COUPLE_COMMENT.ID.eq(id)
                        ).execute();
                    } else {
                        //审核失败
                        dslContext.update(
                                COUPLE_COMMENT
                        ).set(
                                COUPLE_COMMENT.STATS, (Enum_CommentStats.Pass.getCode())
                        ).where(
                                COUPLE_COMMENT.ID.eq(id)
                        ).execute();
                    }


                });

                return suc(true, 1, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getCommentListByType {
        private Enum_CommentType commentType;
        private String bsId;
        private String parentId; // 默认0
        private String userId;
        private Integer cpage;
        private Integer pagesize;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class VPO_getCommentListByType {

        private String id;
        @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;
        private String content;
        private Integer zan;
        private String userId;
        private String nickName;
        private String cover;
        private Boolean selfZan;
    }

    /**
     * 查询评论--评论类型
     *
     * @param model
     * @return
     */
    public DataBean getCommentListByType(
            Model_getCommentListByType model
    ) {
        if (model.getParentId() == null) {
            model.setParentId("0");
        }
        try {
            return dslContext.transactionResult(ctx -> {
                //todo

                int count = dslContext.selectCount()
                        .from(
                                COUPLE_COMMENT
                        ).where(
                                COUPLE_COMMENT.COMMENT_TYPE.eq(model.getCommentType().getCode())
                        ).and(
                                COUPLE_COMMENT.REPLY_ID.eq(model.getParentId())
                        )
                        .and(COUPLE_COMMENT.MAIN_ID.eq(model.getBsId()))
                        .and(COUPLE_COMMENT.STATS.eq(Enum_CommentStats.Apply.getCode()))
                        .fetchOne().value1();
                if (count == 0) {
                    return DataBean.sucEmpty();
                }
                List<VPO_getCommentListByType> list = dslContext.select(
                                CoupleComment.COUPLE_COMMENT.ID.as("id"),
                                CoupleComment.COUPLE_COMMENT.CREATE_TIME.as("createTime"),
                                CoupleComment.COUPLE_COMMENT.CONTENT.as("content"),
                                CoupleComment.COUPLE_COMMENT.ZAN_NUM.as("zan"),
                                BS_USERLAYOUT_USERINFOR.ID.as("userId"),
                                BS_USERLAYOUT_USERINFOR.NICKNAME.as("nickName"),
                                BS_USERLAYOUT_USERINFOR.COVER.as("cover"),
                                DSL.field("if(IFNULL(couple_commentZan.commentId,true),false,true)").as("selfZan")
                        ).from(
                                DSL.select(
                                                COUPLE_COMMENT.ID.as("id"),
                                                COUPLE_COMMENT.USER_ID.as("userId")
                                        ).from(
                                                COUPLE_COMMENT
                                        ).where(
                                                COUPLE_COMMENT.COMMENT_TYPE.eq(model.getCommentType().getCode())
                                        ).and(
                                                COUPLE_COMMENT.REPLY_ID.eq(model.getParentId())
                                        )
                                        .and(COUPLE_COMMENT.MAIN_ID.eq(model.getBsId()))
                                        .and(COUPLE_COMMENT.STATS.eq(Enum_CommentStats.Apply.getCode()))
                                        .orderBy(
                                                COUPLE_COMMENT.IS_TOP.desc(),
                                                COUPLE_COMMENT.CREATE_TIME.desc()
                                        ).limit(
                                                model.getCpage() * model.getPagesize(), model.getPagesize()
                                        ).asTable("t")
                        )
                        .leftJoin(COUPLE_COMMENT).on(COUPLE_COMMENT.ID.eq("t.id"))
                        .leftJoin(BS_USERLAYOUT_USERINFOR).on(BS_USERLAYOUT_USERINFOR.ID.eq("t.userId"))
                        .leftJoin(COUPLE_COMMENTZAN).on(COUPLE_COMMENTZAN.COMMENTID.eq(COUPLE_COMMENT.ID).and(COUPLE_COMMENTZAN.USERID.eq(model.getUserId())))
                        .fetchInto(VPO_getCommentListByType.class);
                dslContext.commit();
                return suc(list, count, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_doZan {
        private String userId;
        private String commentId;
    }


    /**
     * 点赞
     *
     * @param model
     * @return
     */
    public DataBean doZan(
            Model_doZan model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                RLock lock = redissonClient.getFairLock("comment:zan:" + model.getCommentId());
                lock.lock(10, TimeUnit.SECONDS);

                int count = dslContext.selectCount().from(
                        COUPLE_COMMENTZAN
                ).where(
                        COUPLE_COMMENTZAN.COMMENTID.eq(model.getCommentId())
                ).and(COUPLE_COMMENTZAN.USERID.eq(model.getUserId())).fetchOne().value1();

                dslContext.update(
                        COUPLE_COMMENT
                ).set(
                        COUPLE_COMMENT.ZAN_NUM, COUPLE_COMMENT.ZAN_NUM.add(count > 0 ? -1 : 1)
                ).where(
                        model.getCommentId()
                ).execute();
                lock.unlock();
                dslContext.commit();
                return suc(true, 1, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }
}
